package in.muton.wicket.extensions.upload;

import in.muton.edushare.EduShareApplication;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.wicket.Application;
import org.apache.wicket.Component;
import org.apache.wicket.IInitializer;
import org.apache.wicket.RequestCycle;
import org.apache.wicket.ResourceReference;
import org.apache.wicket.behavior.AbstractBehavior;
import org.apache.wicket.behavior.IBehavior;
import org.apache.wicket.extensions.ajax.markup.html.form.upload.UploadProgressBar.ComponentInitializer;
import org.apache.wicket.markup.ComponentTag;
import org.apache.wicket.markup.html.CSSPackageResource;
import org.apache.wicket.markup.html.JavascriptPackageResource;
import org.apache.wicket.markup.html.WebMarkupContainer;
import org.apache.wicket.markup.html.form.Form;
import org.apache.wicket.markup.html.form.upload.FileUploadField;
import org.apache.wicket.markup.html.image.Image;
import org.apache.wicket.markup.html.panel.Panel;
import org.apache.wicket.model.IModel;

public class UploadProcessProgressBar extends Panel {

	/** Initializer for this component, bind to static resource */
	public final static class ComponentInitializer implements IInitializer{

		public void init(Application application) {
			// Register Shared Resources here
			EduShareApplication.get().getSharedResources().add(RESOURCE_NAME, new UploadProcessStatusResource());
		}
		
	}
	
	private static final String RESOURCE_NAME = UploadProcessProgressBar.class.getName();
	private static final ResourceReference CSS = new ResourceReference(UploadProcessProgressBar.class, "uploadProcessProgressBar.css");
	private static final ResourceReference JS =  new ResourceReference(UploadProcessProgressBar.class, "uploadProcessProgressBar.js");
	private final Form form;
	private static final Log log = LogFactory.getLog(UploadProcessProgressBar.class);
	public UploadProcessProgressBar(String id, final Form form) {
		this(id, form, null);
	}

	public UploadProcessProgressBar(String id, final Form form, FileUploadField uploadField) {
		super(id);
		this.form = form;
		setOutputMarkupId(true);
		form.setOutputMarkupId(true);
		setRenderBodyOnly(true);
		
		add(JavascriptPackageResource.getHeaderContribution(JS));
		
		ResourceReference css = getCSS();
		if(css!=null){
			add(CSSPackageResource.getHeaderContribution(css));
		}
		
		final WebMarkupContainer barDiv = new WebMarkupContainer("bar");
		barDiv.setOutputMarkupId(true);
		add(barDiv);
		
		final WebMarkupContainer statusDiv = new WebMarkupContainer("status");
		statusDiv.setOutputMarkupId(true);
		add(statusDiv);
		
		final WebMarkupContainer processingImageDiv = new WebMarkupContainer("wheelImageContainer");
		processingImageDiv.setOutputMarkupId(true);
		processingImageDiv.add(new Image("wheelImage", new ResourceReference(UploadProcessProgressBar.class,"ajax-loader.gif")));
		add(processingImageDiv);
		
		if(!(RequestCycle.get().getRequest() instanceof UploadProcessWebRequest) && 
		   !(RequestCycle.get().getRequest() instanceof MultipartRequest)){
			log.warn("UploadProgressBar will not work without an UploadProcessWebRequest. See the javadoc for details.");
		}
		
		form.add(new FormEnabler(this, statusDiv, barDiv, processingImageDiv, uploadField));
		
	}

	private ResourceReference getCSS() {
		return CSS;
	}
	
	protected void onRemove(){
		for(IBehavior behavior : form.getBehaviors()){
			if(behavior instanceof FormEnabler){
				if(((FormEnabler)behavior).getUploadProcessProgressBar() == this){
					form.remove(behavior);
					break;
				}
			}
		}
		super.onRemove();
	}
	
	private static class FormEnabler extends AbstractBehavior{
		private final Component status, bar, uploadField, processing;
		private final UploadProcessProgressBar uppbar;
		
		public FormEnabler(UploadProcessProgressBar uppbar, Component status, Component bar, Component processingImageDiv, Component uploadField){
			this.uppbar = uppbar;
			this.status =status;
			this.bar = bar;
			this.uploadField = uploadField;
			this.processing = processingImageDiv;
		}
		
		@Override
		public void onComponentTag(Component component, ComponentTag tag) {
			ResourceReference ref = new ResourceReference(RESOURCE_NAME);
			String uploadFieldId = (uploadField == null)? "" : uploadField.getMarkupId();
			tag.put("onsubmit", "var def=new Wicket.WUPB.Def('" + component.getMarkupId() + "', '" +
					status.getMarkupId() + "', '" + bar.getMarkupId() + "', '" +
					processing.getMarkupId() + "', '"+
					component.getPage().urlFor(ref) + "','" + uploadFieldId +
					"'); Wicket.WUPB.start(def);");
			//TODO:
			//this method, add on Remove, add css aND js files, change application start-up, test
		}
		
		public UploadProcessProgressBar getUploadProcessProgressBar(){
			return uppbar;
		}
		
	}

}
